#pragma once
#include "TcpServer.hpp"
#include "HttpProtocol.hpp"
#include "Session.hpp"
using handler_arg_t = std::function<HttpResponse(HttpRequest &)>;
const int defaultport = 8080;
const std::string Dir = "wwwroot";
class HttpServer
{
public:
    HttpServer(int port = defaultport) : _tcpserver(std::make_unique<TcpServer>(port)), _session_manager(std::make_unique<SessionManager>())
    {
        _tcpserver->Init([this](Socket *newsockp)
                         { this->HandlerRequest(newsockp); });
    }
    ~HttpServer()
    {
    }
    // 注册方法
    void Register(const std::string &name, handler_arg_t method)
    {
        _handler[name] = method;
    }
    void Start()
    {
        //_tcpserver->Init();
        _tcpserver->Start();
    }

    void HandlerRequest(Socket *newsockp)
    {
        // GET /favicon.ico HTTP/1.1
        // Host: 1.94.214.183:8080
        // Connection: keep-alive
        // User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0
        // DNT: 1
        // Accept: image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8
        // Referer: http://1.94.214.183:8080/
        // Accept-Encoding: gzip, deflate
        // Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
        //
        std::string req;
        newsockp->Recv(&req);
        // std::cout << "Prase之前:" << std::endl;
        // std::cout << req;

        // 这里不进行完整性检查了
        HttpRequest request;

        // 反序列化
        request.Deserialize(req);
        std::cout << "Prase之后:" << std::endl;
        request.Print();
        //  std::cout << req;

        std::string url = Dir + request.Url();
        if (url.back() == '/')
        {
            url += "index.html";
        }
        // 用户想要的是请求的文件，也就是url
        std::cout << "用户想要的url: " << url << std::endl;
        HttpResponse res;
        std::string resp;
        static int num = 0;
        if (request.Url() == "/login")
        {
            std::string sessionid = request.SessionId();
            if (sessionid.empty())
            {
                std::string user = "user-"+std::to_string(num++);
                session_ptr s = std::make_shared<Session>(user);
                sessionid = _session_manager->AddSession(s);
                request.SetSessionId(sessionid);
                LOG(LogLevel::DEBUG)<<user<<"被添加,"<<"sessionid是"<<sessionid;
                //std::cout<<"session_manager"<<":"<<_session_manager.get()<<std::endl;
                _session_manager->Print();
            }
        }
        else
        {
            std::string sessionid = request.SessionId();
            if(!sessionid.empty())
            {
                //std::cout<<"session_manager"<<":"<<_session_manager.get()<<std::endl;
                _session_manager->Print();
                session_ptr s = _session_manager->GetSession(sessionid);

                if(s==nullptr)
                {
                    LOG(LogLevel::DEBUG)<<"cookie: "<<sessionid<<"已过期";
                }
                else
                {
                    LOG(LogLevel::DEBUG)<<s->User()<<"正在活跃,"<<"sessionid是"<<sessionid;
                }
            }
        }
        // 如果有参数进行一系列处理
        if (request.IsHasArgs())
        {
            res = _handler[request.Url()](request);
        }
        else
        {
            res.BuildResp(url);
        }
        resp = res.Serialize(url, request);
        // std::cout<<"resp: "<<std::endl;
        // std::cout<<resp;
        //  resp = "HTTP/1.1 200 OK\r\n";
        //  resp += "\r\n";
        //  std::string body = "<!DOCTYPE html>\n"
        //                     "<html lang=\"en\">\n"
        //                     "<head>\n"
        //                     "    <meta charset=\"UTF-8\">\n"
        //                     "    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n"
        //                     "    <title>Hello World</title>\n"
        //                     "</head>\n"
        //                     "<body>\n"
        //                     "    <h1>Hello, World!</h1>\n"
        //                     "</body>\n"
        //                     "</html>";
        //  resp += body;

        std::cout << "用户响应:------------------" << std::endl;
        std::cout << resp << std::endl;
        std::cout << "-----------------------------------" << std::endl;
        newsockp->Send(resp);
        return;
    }

private:
    std::unique_ptr<TcpServer> _tcpserver;
    std::unique_ptr<SessionManager> _session_manager;
    std::unordered_map<std::string, handler_arg_t> _handler;
};